class GeoService {

    boolean transactional = false

    double EARTH_RADIUS = 6378.137; // km  FIXME is this correct?


    boolean inRect(double lat, double lon, double latMin, double latMax,
                   double lonMin, double lonMax) {
        //FIXME 
        return Math.signum(latMin - lat) * Math.signum(latMax - lat) < 0 && Math.signum(lonMin - lon) * Math.signum(lonMax - lon) < 0
    }

    
    double rad(double d)
    {
        return d * Math.PI / 180.0;
    }


    /**
    * kilometers
    */
    double getDistance(geoPoint1, geoPoint2) {
        return getDistance(geoPoint1.latitude, geoPoint1.longitude, geoPoint2.latitude, geoPoint2.longitude)
    }

    //kilometers 
    double getDistance(double lat1, double lng1, double lat2, double lng2)
    {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);

        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        // s = Math.round(s * 10000) / 10000;
        return s;
    }

    // inaccuracy 0.3%  howto improve?
    double getLngDiff4Distance(double lat1, double lng1, double distance) {
        def unit = getDistance(lat1, lng1, lat1, lng1 + 1)
        def lngDistance = (distance/unit)* 1 
        return lngDistance
    }


    //  poins[poinst.size-1] == points[0]
    boolean inPolygon(point, points) {
        int crossings = 0;
        for (int i = 0; i < points.size() - 1; i++) {
            double slope = (points[i + 1].longitude - points[i].longitude) / (points[i + 1].latitude - points[i].latitude);
            boolean cond1 = (points[i].latitude <= point.latitude) && (point.latitude < points[i + 1].latitude);
            boolean cond2 = (points[i + 1].latitude <= point.latitude) && (point.latitude < points[i].latitude);
            boolean cond3 = point.longitude < slope * (point.latitude - points[i].latitude) + points[i].longitude;
            if ((cond1 || cond2) && cond3) {
                crossings++;
            }
        }
        return (crossings % 2 != 0);

    }
}

